﻿using Microsoft.Xna.Framework;
using Microsoft.Xna.Framework.Graphics;
using System;
using Terraria;
using Terraria.DataStructures;
using Terraria.GameContent;
using Terraria.ID;
using Terraria.Localization;
using Terraria.ModLoader;
using Terraria.ObjectData;
using Terraria.UI;

namespace HardcoreGame.Content.Tiles.Machines
{
    public class DryingRack : ModTile
    {
        public static int GetTEIndex(int i, int j)
        {
            return ModContent.GetInstance<DryingRackTE>().Find(i - Main.tile[i, j].TileFrameX % 108 / 18, j - Main.tile[i, j].TileFrameY % 54 / 18);
        }

        public override void SetStaticDefaults()
        {
            TileID.Sets.DrawsWalls[Type] = true;
            TileID.Sets.DontDrawTileSliced[Type] = true;
            TileID.Sets.IgnoresNearbyHalfbricksWhenDrawn[Type] = true;
            TileID.Sets.IsAMechanism[Type] = true;
            Main.tileFrameImportant[Type] = true;
            Main.tileNoAttach[Type] = true;
            Main.tileLavaDeath[Type] = true;
            TileObjectData.newTile.CopyFrom(TileObjectData.Style3x3);
            TileObjectData.newTile.Width = 7;
            TileObjectData.newTile.Height = 3;
            TileObjectData.newTile.CoordinateHeights = [16, 16, 16];
            TileObjectData.newTile.HookPostPlaceMyPlayer = new PlacementHook(new Func<int, int, int, int, int, int, int>(ModContent.GetInstance<DryingRackTE>().Hook_AfterPlacement), -1, 0, false);
            TileObjectData.addTile(Type);
            LocalizedText name = CreateMapEntryName();
            AddMapEntry(new Color(117, 89, 51), name);
            RegisterItemDrop(ModContent.ItemType<Items.Placeable.Machines.DryingRack>());
        }

        public override void MouseOver(int i, int j)
        {
            int index = GetTEIndex(i, j);
            if (index == -1)
            {
                return;
            }

            DryingRackTE entity = (DryingRackTE)TileEntity.ByID[index];
            Player player = Main.LocalPlayer;
            Item selectedItem = player.inventory[player.selectedItem];
            int slot = GetSlotFromPosition(i, j);

            if (!selectedItem.IsAir)
            {
                player.cursorItemIconID = selectedItem.type;
                player.noThrow = 2;
                player.cursorItemIconEnabled = true;
                return;
            }

            if (!entity.items[slot].IsAir)
            {
                player.cursorItemIconID = entity.items[slot].type;
                player.noThrow = 2;
                player.cursorItemIconEnabled = true;
            }
        }

        private static int GetSlotFromPosition(int i, int j)
        {
            Tile tile = Main.tile[i, j];
            int frameX = tile.TileFrameX % 108;
            int relativeX = i * 16 - (i - frameX / 18) * 16;
            if (relativeX < 38) return 0;
            if (relativeX < 76) return 1;
            return 2;
        }

        public override void DrawEffects(int i, int j, SpriteBatch spriteBatch, ref TileDrawInfo drawData)
        {
            if (ModContent.GetInstance<DryingRackTE>().Find(i, j) != -1)
            {
                Main.instance.TilesRenderer.AddSpecialLegacyPoint(i, j);
            }
        }

        public override void SpecialDraw(int i, int j, SpriteBatch spriteBatch)
        {
            int index = ModContent.GetInstance<DryingRackTE>().Find(i, j);
            if (index == -1) return;
            DryingRackTE entity = (DryingRackTE)TileEntity.ByID[index];
            var originalSamplerState = spriteBatch.GraphicsDevice.SamplerStates[0];
            spriteBatch.GraphicsDevice.SamplerStates[0] = SamplerState.PointClamp;
            try
            {
                for (int slot = 0; slot < 3; slot++)
                {
                    Item item = entity.items[slot];
                    if (item.IsAir) continue;

                    DryingRackTE.GetItemDrawFrame(item.type, out Texture2D itemTexture, out Rectangle itemFrame);
                    float scale = 1f;
                    float maxSize = 40f;
                    if (itemFrame.Width > maxSize || itemFrame.Height > maxSize)
                    {
                        scale = itemFrame.Width <= itemFrame.Height
                            ? maxSize / itemFrame.Height
                            : maxSize / itemFrame.Width;
                    }
                    scale *= item.scale;
                    Color lightColor = Lighting.GetColor(i + 1, j + 1);
                    Color currentColor = lightColor;
                    float scale2 = 1f;
                    ItemSlot.GetItemLight(ref currentColor, ref scale2, item, false);
                    scale *= scale2;
                    Vector2 offSet = new(Main.offScreenRange, Main.offScreenRange);
                    float xOffset = 24 + slot * 38;
                    Vector2 drawPos = new Vector2(
                        i * 16 - (int)Main.screenPosition.X + xOffset,
                        j * 16 - (int)Main.screenPosition.Y + 24) + offSet;
                    float rotation = -MathHelper.PiOver4;
                    Vector2 origin = itemFrame.Size() / 2f;
                    if (entity.IsItemDrying(slot))
                    {
                        float progress = 1f - (entity.waterContent[slot] / 100f);
                        DrawProgressBar(spriteBatch, drawPos, progress, -30);
                    }
                    spriteBatch.Draw(
                        itemTexture,
                        drawPos,
                        itemFrame,
                        currentColor,
                        rotation,
                        origin,
                        scale,
                        SpriteEffects.None,
                        0f);

                    if (item.color != default)
                    {
                        spriteBatch.Draw(
                            itemTexture,
                            drawPos,
                            itemFrame,
                            item.GetColor(lightColor),
                            rotation,
                            origin,
                            scale,
                            SpriteEffects.None,
                            0f);
                    }
                }
            }
            finally
            {
                spriteBatch.GraphicsDevice.SamplerStates[0] = originalSamplerState;
            }
        }
        private static void DrawProgressBar(SpriteBatch spriteBatch, Vector2 drawPos, float progress, int yOffset)
        {
            int barWidth = 24;
            int barHeight = 6;

            Rectangle bgRect = new(
                (int)(drawPos.X - barWidth / 2),
                (int)(drawPos.Y + yOffset),
                barWidth,
                barHeight);

            Rectangle fgRect = new(
                bgRect.X + 1,
                bgRect.Y + 1,
                (int)((barWidth - 2) * progress),
                barHeight - 2);

            Color bgColor = new(0, 0, 0, 180);
            Color fgColor = Color.Lerp(new Color(255, 40, 40), new Color(40, 255, 40), progress);

            spriteBatch.Draw(TextureAssets.MagicPixel.Value, bgRect, Color.White);
            spriteBatch.Draw(TextureAssets.MagicPixel.Value, bgRect, bgColor);
            spriteBatch.Draw(TextureAssets.MagicPixel.Value, fgRect, fgColor);

            spriteBatch.Draw(TextureAssets.MagicPixel.Value, new Rectangle(bgRect.X, bgRect.Y, bgRect.Width, 1), Color.White);
            spriteBatch.Draw(TextureAssets.MagicPixel.Value, new Rectangle(bgRect.X, bgRect.Y + barHeight - 1, bgRect.Width, 1), Color.White);
            spriteBatch.Draw(TextureAssets.MagicPixel.Value, new Rectangle(bgRect.X, bgRect.Y, 1, barHeight), Color.White);
            spriteBatch.Draw(TextureAssets.MagicPixel.Value, new Rectangle(bgRect.X + barWidth - 1, bgRect.Y, 1, barHeight), Color.White);
        }

        public override void KillMultiTile(int i, int j, int frameX, int frameY)
        {
            ModContent.GetInstance<DryingRackTE>().Kill(i, j);
        }

        public override bool RightClick(int i, int j)
        {
            DryingRackTE.OnPlayerInteraction(Main.LocalPlayer, i, j);
            return true;
        }
    }
}